package teachers;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

/**
 * 
 * @author xia hdfs常用api
 */
public class HDFSAPITest {

	public static void main(String[] args) throws IOException, InterruptedException, URISyntaxException {
		Configuration conf = new Configuration();
		FileSystem fs = FileSystem.get(new URI("hdfs://192.168.3.101:9000"), conf, "hadoop");

		// 创建文件夹
		Path path = new Path("/WordCount");
		// 文件是否存在
		boolean b = fs.exists(path);
		if (!b) {
			fs.mkdirs(path);
		}

		// 删除文件夹
		fs.delete(path);
		fs.deleteOnExit(path);
		fs.delete(path, true);

		// 获取指定目录下的文件列表 只能获取文件列表，获取不到文件夹 shift+ctrl+L
		RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(path, false);
		// 遍历迭代器
		while (listFiles.hasNext()) {
			LocatedFileStatus next = listFiles.next();
			System.out.println(next.getPath());
			System.out.println(next.getReplication());
			// 返回每一个文件的块信息，数组长度代表块的个数，每一个块代表数组中的一个元素
			BlockLocation[] blockLocations = next.getBlockLocations();
			for (BlockLocation bl : blockLocations) {
				System.out.println(bl);
				System.out.println("block size=" + bl.getLength());
			}
		}

		// 获取指定目录下的文件状态信息
		FileStatus[] listStatus = fs.listStatus(new Path("/"));
		for (FileStatus fst : listStatus) {
			System.out.println(fst);
			System.out.println(fst.isDirectory());
			System.out.println(fst.isFile());
			System.out.println(fst.getBlockSize());
		}

		// 流的形式上传/下载 IOUtils工具类
		// 文件上传：本地（输入流）普通的java输入流-----hdfs（输出流）
		FileInputStream in = new FileInputStream(new File("E:\\wordcount.txt"));
		FSDataOutputStream out = fs.create(new Path("/apitest/stream")); // 必须指定一个文件名
		IOUtils.copyBytes(in, out, 4096);

		// 文件下载：hdfs（输入流）----本地（输出流）
		FSDataInputStream fsin = fs.open(new Path("/wordcount.txt"));
		FileOutputStream fsout = new FileOutputStream(new File("D:\\soft\\"));
		IOUtils.copyBytes(fsin, fsout, 4096);

		// IOUtils操作完会自动关闭流，不用再执行 in.close() 和 out.close()

	}

}
